"""
缓存服务
提供内存缓存和Redis缓存功能
"""
import json
import time
import hashlib
from typing import Any, Optional, Dict
from functools import wraps

# Redis导入已移除，现在只使用内存缓存
REDIS_AVAILABLE = False

from core.config import settings
from core.logging_config import get_logger

# 日志记录器
logger = get_logger("cache_service")


class CacheService:
    """缓存服务（仅使用内存缓存）"""
    
    def __init__(self):
        self.memory_cache: Dict[str, Dict[str, Any]] = {}
        self.default_ttl = 3600  # 默认1小时
        self.max_memory_size = 1000  # 内存缓存最大条目数
    
        
    def _generate_key(self, prefix: str, *args, **kwargs) -> str:
        """生成缓存键"""
        # 将参数转换为字符串并排序
        args_str = "_".join(str(arg) for arg in args)
        kwargs_str = "_".join(f"{k}={v}" for k, v in sorted(kwargs.items()))
        
        # 组合键
        key = f"{prefix}:{args_str}"
        if kwargs_str:
            key += f":{kwargs_str}"
        
        # 如果键太长，使用MD5哈希
        if len(key) > 250:
            key_hash = hashlib.md5(key.encode()).hexdigest()
            key = f"{prefix}:{key_hash}"
        
        return key
    
    def _is_expired(self, cache_item: Dict[str, Any]) -> bool:
        """检查缓存项是否过期"""
        return cache_item.get('expires_at', 0) < time.time()
    
    def _cleanup_memory_cache(self):
        """清理过期的内存缓存"""
        current_time = time.time()
        expired_keys = []
        
        for key, item in self.memory_cache.items():
            if self._is_expired(item):
                expired_keys.append(key)
        
        for key in expired_keys:
            del self.memory_cache[key]
        
        # 如果缓存仍然太大，删除最旧的条目
        if len(self.memory_cache) > self.max_memory_size:
            sorted_items = sorted(
                self.memory_cache.items(),
                key=lambda x: x[1].get('created_at', 0)
            )
            
            items_to_remove = len(self.memory_cache) - self.max_memory_size + 100
            for i in range(items_to_remove):
                if i < len(sorted_items):
                    del self.memory_cache[sorted_items[i][0]]
    
    async def get(self, key: str) -> Optional[Any]:
        """获取缓存值"""
        try:
            # 直接从内存缓存获取
            cache_item = self.memory_cache.get(key)
            if cache_item and not self._is_expired(cache_item):
                cache_item['last_accessed'] = time.time()
                return cache_item['value']
            
            return None
        except Exception as e:
            logger.error(f"获取缓存失败: {e}")
            return None
    
    async def set(
        self, 
        key: str, 
        value: Any, 
        ttl: Optional[int] = None
    ) -> bool:
        """设置缓存值"""
        try:
            if ttl is None:
                ttl = self.default_ttl
            
            expires_at = time.time() + ttl
            
            # 直接存储到内存缓存
            self.memory_cache[key] = {
                'value': value,
                'created_at': time.time(),
                'last_accessed': time.time(),
                'expires_at': expires_at
            }
            
            # 清理内存缓存
            self._cleanup_memory_cache()
            
            return True
        except Exception as e:
            logger.error(f"设置缓存失败: {e}")
            return False
    
    async def delete(self, key: str) -> bool:
        """删除缓存值"""
        try:
            # 直接从内存缓存删除
            if key in self.memory_cache:
                del self.memory_cache[key]
            
            return True
        except Exception as e:
            logger.error(f"删除缓存失败: {e}")
            return False
    
    async def clear(self, pattern: str = "*") -> bool:
        """清空缓存"""
        try:
            # 清空内存缓存
            if pattern == "*":
                self.memory_cache.clear()
            else:
                keys_to_delete = [k for k in self.memory_cache.keys() if pattern in k]
                for key in keys_to_delete:
                    del self.memory_cache[key]
            
            return True
        except Exception as e:
            logger.error(f"清空缓存失败: {e}")
            return False
    
    async def exists(self, key: str) -> bool:
        """检查缓存是否存在"""
        try:
            # 直接检查内存缓存
            cache_item = self.memory_cache.get(key)
            return cache_item is not None and not self._is_expired(cache_item)
        except Exception as e:
            logger.error(f"检查缓存存在性失败: {e}")
            return False
    
    async def ttl(self, key: str) -> int:
        """获取缓存剩余时间"""
        try:
            # 直接检查内存缓存
            cache_item = self.memory_cache.get(key)
            if cache_item and not self._is_expired(cache_item):
                return int(cache_item['expires_at'] - time.time())
            
            return -1
        except Exception as e:
            logger.error(f"获取缓存TTL失败: {e}")
            return -1
    
    def get_cache_stats(self) -> Dict[str, Any]:
        """获取缓存统计信息"""
        return {
            'memory_cache_size': len(self.memory_cache),
            'max_memory_size': self.max_memory_size,
            'default_ttl': self.default_ttl,
            'cache_type': 'memory_only'
        }


# 全局缓存服务实例
cache_service = CacheService()


def cache_result(
    prefix: str,
    ttl: Optional[int] = None,
    key_generator: Optional[callable] = None
):
    """缓存装饰器"""
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            # 生成缓存键
            if key_generator:
                key = key_generator(func.__name__, *args, **kwargs)
            else:
                key = cache_service._generate_key(prefix, *args, **kwargs)
            
            # 尝试从缓存获取
            cached_result = await cache_service.get(key)
            if cached_result is not None:
                logger.debug(f"缓存命中: {key}")
                return cached_result
            
            # 执行函数
            logger.debug(f"缓存未命中，执行函数: {key}")
            result = await func(*args, **kwargs)
            
            # 存储到缓存
            await cache_service.set(key, result, ttl)
            
            return result
        
        return wrapper
    return decorator


class QueryCache:
    """数据库查询缓存"""
    
    def __init__(self, cache_service: CacheService):
        self.cache = cache_service
        self.query_ttl = 1800  # 查询缓存30分钟
    
    def _generate_query_key(self, query: str, params: tuple = ()) -> str:
        """生成查询缓存键"""
        query_hash = hashlib.md5((query + str(params)).encode()).hexdigest()
        return f"query:{query_hash}"
    
    async def get_query_result(self, query: str, params: tuple = ()):
        """获取查询缓存"""
        key = self._generate_query_key(query, params)
        return await self.cache.get(key)
    
    async def set_query_result(self, query: str, params: tuple = (), result: Any = None):
        """设置查询缓存"""
        key = self._generate_query_key(query, params)
        return await self.cache.set(key, result, self.query_ttl)
    
    async def invalidate_query_cache(self, table_name: str):
        """失效表相关的查询缓存"""
        pattern = f"query:*{table_name}*"
        return await self.cache.clear(pattern)


class AnalysisCache:
    """分析结果缓存"""
    
    def __init__(self, cache_service: CacheService):
        self.cache = cache_service
        self.analysis_ttl = 3600  # 分析结果缓存1小时
    
    def _generate_analysis_key(self, analysis_type: str, params: Dict[str, Any]) -> str:
        """生成分析缓存键"""
        params_str = json.dumps(params, sort_keys=True)
        params_hash = hashlib.md5(params_str.encode()).hexdigest()
        return f"analysis:{analysis_type}:{params_hash}"
    
    async def get_analysis_result(self, analysis_type: str, params: Dict[str, Any]):
        """获取分析结果缓存"""
        key = self._generate_analysis_key(analysis_type, params)
        return await self.cache.get(key)
    
    async def set_analysis_result(self, analysis_type: str, params: Dict[str, Any], result: Any):
        """设置分析结果缓存"""
        key = self._generate_analysis_key(analysis_type, params)
        return await self.cache.set(key, result, self.analysis_ttl)
    
    async def invalidate_analysis_cache(self, analysis_type: str = None):
        """失效分析缓存"""
        if analysis_type:
            pattern = f"analysis:{analysis_type}:*"
        else:
            pattern = "analysis:*"
        return await self.cache.clear(pattern)


class ReportCache:
    """报告缓存"""
    
    def __init__(self, cache_service: CacheService):
        self.cache = cache_service
        self.report_ttl = 7200  # 报告缓存2小时
    
    def _generate_report_key(self, report_id: int) -> str:
        """生成报告缓存键"""
        return f"report:{report_id}"
    
    async def get_report_content(self, report_id: int):
        """获取报告内容缓存"""
        key = self._generate_report_key(report_id)
        return await self.cache.get(key)
    
    async def set_report_content(self, report_id: int, content: Any):
        """设置报告内容缓存"""
        key = self._generate_report_key(report_id)
        return await self.cache.set(key, content, self.report_ttl)
    
    async def invalidate_report_cache(self, report_id: int = None):
        """失效报告缓存"""
        if report_id:
            key = self._generate_report_key(report_id)
            return await self.cache.delete(key)
        else:
            return await self.cache.clear("report:*")


# 创建专门的缓存实例
query_cache = QueryCache(cache_service)
analysis_cache = AnalysisCache(cache_service)
report_cache = ReportCache(cache_service)


async def cache_statistics():
    """获取缓存统计信息"""
    stats = cache_service.get_cache_stats()
    
    # 添加内存缓存效率统计
    total_access = 0
    hit_count = 0
    
    # 简单的命中率计算（可以根据需要扩展）
    stats['memory_hit_rate'] = 'N/A'
    stats['cache_efficiency'] = 'good'
    
    return stats